﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using TorchView.GameContent.Data;
using System.IO;

namespace TorchView.GameContent.Effects
{
    public class EffectList
    {
        #region Static Region
        private static EffectList _list;
        public static EffectList DefaultList
        {
            get
            {
                if (_list == null)
                    _list = LoadEffectList();
                return _list;
            }
        }
        #endregion

        public const string BLOCK_NAME = "EFFECTLIST";

        private Effect[] effects;
        private SortedDictionary<string, SortedList<string, Effect>> effectCategories;
        private SortedList<string, Effect> effectList;

        private EffectList() {
            effectCategories = new SortedDictionary<string, SortedList<string,Effect>>();
            effectList = new SortedList<string, Effect>();
        }

        private static EffectList LoadEffectList()
        {
            Stream stream = PakReader.OpenFile("media/EFFECTSLIST.DAT.adm");
            DataBlock block = AdmSerializer.Load(stream);
            EffectList list = new EffectList();
            list.LoadFromDataBlock(block);
            return list;
        }

        public void LoadFromDataBlock(DataBlock block)
        {
            if (block == null)
                throw new ArgumentNullException("block");
            if (block.Name != BLOCK_NAME)
                throw new ArgumentException("Incorrect block type, only " + BLOCK_NAME + " is supported.");

            Length = block.SubBlocks.Count;
            effects = new Effect[Length];

            int index = 0;
            foreach (DataBlock subblock in block.SubBlocks)
            {
                effects[index] = new Effect();
                effects[index].Index = index;
                effects[index].LoadFromDataBlock(subblock);

                SortedList<string, Effect> list;
                if (!effectCategories.TryGetValue(effects[index].Type, out list))
                {
                    list = new SortedList<string, Effect>();
                    effectCategories.Add(effects[index].Type, list);
                }
                list.Add(effects[index].Name, effects[index]);
                effectList.Add(effects[index].Name, effects[index]);

                ++index;
            }
        }

        public Effect[] Effects { get { return effects; } }
        public int Length { get; private set; }

        public Effect this[int i]
        {
            get
            {
                if (i >= 0 && i < effects.Length)
                    return effects[i];
                else
                    return null;
            }
        }

        public Effect this[string name]
        {
            get
            {
                Effect effect;
                if (effectList.TryGetValue(name, out effect))
                    return effect;
                else
                    return null;
            }
        }

        public IEnumerable<String> Categories
        {
            get { return effectCategories.Keys;}
        }

        public IList<Effect> GetByCategory(String cat)
        {
            SortedList<string, Effect> list;
            if (effectCategories.TryGetValue(cat, out list))
                return list.Values;
            else
                return null;
        }

    }
}
